home *** CD-ROM | disk | FTP | other *** search
- var
- cancelled : boolean;
- inbuffer : line;
-
- function charin(withecho: boolean):char; forward;
-
- procedure sendout(ch: char);
-
- {Character output - bypasses word-wrap; also performs
- "pause" and "abort" input character checks.}
-
- var temp: char;
- tctl: boolean;
-
- begin
- if not cancelled then begin
- if inready then begin
- temp := charin(noecho);
- if (temp = pause) or (upcase(temp) = 'S') then begin
- tctl := controls;
- controls := true;
- temp := charin(noecho);
- controls := tctl;
- end;
- if (temp = abort) or (upcase(temp) = 'C') then cancelled := true;
- end;
- xmitchar(ch);
- write(ch);
- if printon then write(lst, ch);
- if (ch = cr) and (lf = null) then writeln;
- end;
- end;
-
- procedure flushbuff;
-
- var
- outpointer: byte;
-
- begin
- if length(buffer) > lastspace then
- for outpointer := lastspace + 1 to length(buffer) do
- sendout(buffer[outpointer]);
- lastspace := length(buffer);
- end;
-
- procedure resetbuff;
-
- begin
- bufpointer := 0;
- lastspace := 0;
- charcount := 0;
- buffer := '';
- end;
-
- procedure charout(ch:char);
-
- {Character output using word-wrap}
-
- var
- buffull : boolean;
- temp : long;
-
- begin
- if caps then ch := upcase(ch);
- if not (ch in [null..#31]) then charcount := succ(charcount);
- if (ch = bs) and (charcount > 0) then charcount := charcount - 1;
- buffer := buffer + ch;
- bufpointer := length(buffer);
- buffull := (charcount + 2 > width);
- if buffull then begin
- if (lastspace > 0)
- then begin
- buffer := copy(buffer, lastspace + 1, bufpointer - lastspace);
- charcount := length(buffer);
- lastspace := 0;
- end {then}
- else begin
- flushbuff;
- resetbuff;
- end; {else}
- sendout(cr);
- sendout(lf);
- end; {if}
- if ch in [null..space] then flushbuff;
- if (ch=cr) then resetbuff;
- end;
-
- procedure stringout(message:line);
-
- var
- charpos: integer;
-
- begin
- for charpos := 1 to length(message) do charout(message[charpos]);
- end;
-
- procedure lineout; (* "forward" declared in MACHDEP *)
-
- begin
- stringout(message);
- charout(cr);
- charout(lf);
- end;
-
- function timedin: boolean;
-
- {returns false if no character received in within
- one second: used for XMODEM and input timeout.}
-
- var times: integer;
-
- begin
- times := 0;
- while (times < 500) and not inready do begin
- times := times + 1;
- delay(2);
- end;
- timedin := inready and cts;
- end;
-
- function charin;
-
- var
- ch: char;
- countime: integer;
-
- begin
- ch := null;
- countime := 0;
- repeat
- if timedin then ch := recvchar else countime := countime + 1;
- if keypressed then read(kbd, ch);
- if countime > 300 then hangup;
- if not cts then ch := cr;
- if (ch <> bs) and not controls then ch := chr(ord(ch) and 127);
- until (ch in [abort, pause, bs, tab, cr, space..#127])
- or (controls and (ch <> null));
- if (ch = #127) and not controls then ch := bs;
- if ch = #$8D then ch := cr;
- if withecho then begin
- sendout(ch);
- if ch = bs then begin sendout(' '); sendout(bs); end;
- end;
- charin := ch;
- end;
-
- procedure flush;
-
- var
- junk: char;
-
- begin
- while inready do junk := charin(noecho);
- clearstatus;
- end;
-
- function inputstring(withecho: boolean): line;
-
- var
- temp: line;
- ch: char;
-
- begin
- temp := '';
- flush;
- repeat
- ch := charin(noecho);
- if (ch = bs) then begin
- if length(temp) > 0 then begin
- temp := copy(temp, 1, length(temp) - 1);
- if withecho then begin
- sendout(bs);
- sendout(space);
- sendout(bs);
- end;
- end;
- end
- else begin
- if (ch <> cr) and (length(temp) < 80)
- and ((ch in [tab, space..#126]) or controls) then begin
- if ch = tab then repeat
- temp := temp + space;
- if withecho then sendout(space);
- until (length(temp) mod 8) = 0
- else begin
- temp := temp + ch;
- if withecho then sendout(ch);
- end; {else}
- end
- else if (ch <> cr) then sendout(bell);
- end;
- until (ch = cr);
- charout(cr); charout(lf);
- inputstring := temp;
- end;
-
- function getinput(prompt:line; maxlength:integer; withecho:boolean):line;
-
- var posn: integer;
- temp: char;
-
- begin
- if cancelled then begin
- cancelled := false;
- lineout(space);
- end;
- if inbuffer = '' then begin
- repeat
- cancelled := false;
- stringout(prompt);
- if bl = bell then stringout(bl);
- until cancelled = false;
- inbuffer := inputstring(withecho);
- end;
- if maxlength = 1 then begin
- if inbuffer = '' then temp := cr else begin
- temp := inbuffer[1];
- inbuffer := copy(inbuffer, 2, length(inbuffer)-1);
- if (length(inbuffer) > 1) and (inbuffer[1] = ';')
- then inbuffer := copy(inbuffer, 2, length(inbuffer)-1);
- end; {else}
- getinput := temp;
- end
- else begin
- posn := pos(';', inbuffer);
- if posn = 0 then posn := length(inbuffer) + 1;
- if posn > maxlength then begin
- posn := maxlength + 1;
- inbuffer := copy(inbuffer, 1, maxlength);
- end;
- getinput := copy(inbuffer, 1, posn - 1);
- if posn >= length(inbuffer)
- then inbuffer := ''
- else inbuffer := copy(inbuffer, posn + 1, length(inbuffer) - posn);
- end;
- end;
-
- function allcaps(letters: person): person;
-
- var
- loop: byte;
- temp: person;
-
- begin
- temp := '';
- for loop := 1 to length(letters) do
- temp := temp + upcase(letters[loop]);
- allcaps := temp;
- end;
-
- procedure awaitcall;
-
- var
- junk: char;
-
- begin
- setbaud(fast);
- writeln(cr + lf + 'Waiting for call...');
- flush;
- repeat
- if keypressed then begin
- read(kbd, junk);
- local := junk = esc;
- if local then setlocal else exitchar := junk;
- end;
- until cts or (exitchar = abort);
- clrscr;
- if exitchar <> abort then begin
- if local then writeln('Local control.') else writeln('On line...');
- delay(400);
- flush;
- junk := charin(noecho);
- if badframe or (junk <> cr) then setbaud(slow);
- end;
- end;
-
- procedure clearsc;
-
- begin
- stringout(cs);
- delay(500); {allows time for slow terminal screen clears}
- end;
-
- function getcap(prompt: line): char;
-
- begin
- getcap := upcase(getinput(prompt, 1, echo));
- end;
-
- function getint(nmax, star: integer; prompt: line): integer;
-
- var temp, test: integer;
- outstr, userin: name;
-
- begin
- str(nmax:4, outstr);
- repeat
- temp := 0;
- userin := getinput(prompt, 4, echo);
- val(userin, temp, test);
- if (temp > nmax) then lineout('Number too large: ' + outstr + ' maximum.');
- until ((test = 0) and (temp >= 0) and (temp <= nmax))
- or (userin = '*') or (userin = '') or (userin = '?') or not cts;
- if userin = '?' then getint := -1
- else if userin = '*' then getint := star
- else if test = 0 then getint := temp
- else getint := 0;
- end;
-
- {Real-time clock support starts here...
- these routines must remain, even if there's
- no clock! To kill clock support, simply set
- "clockin" in BBS.PAS to false.}
-
- type monthname = string[3];
- monames = array[1..12] of monthname;
-
- const months: monames = ('Jan','Feb','Mar','Apr','May','Jun',
- 'Jul','Aug','Sep','Oct','Nov','Dec');
-
- function time(month, date, hour, min, sec: byte): name;
-
- {Returns 14-character string containing time and date}
-
- var
- temps,
- tempm,
- tempd,
- temph: string[2];
-
- begin
- if clockin then begin
- str(sec:2,temps);
- str(min:2,tempm);
- str(hour:2,temph);
- str(date:2,tempd);
- if sec < 10 then temps := '0' + temps[2];
- if min < 10 then tempm := '0' + tempm[2];
- if date < 10 then tempd := '0' + tempd[2];
- time := temph + ':' + tempm + ':' + temps + ' ' + months[month] + tempd;
- end
- else time := '';
- end;
-
- procedure showtime;
-
- var
- message: name;
-
- begin
- if clockin then begin
- clock(month, date, hour, min, sec);
- message := time(month, date, hour, min, sec);
- lineout('Time is: ' + message);
- end;
- end;
-
- procedure calcconnect(var usehour, usemin, usesec: integer);
-
- begin
- clock(month, date, hour, min, sec);
- usemin := 0;
- usehour := 0;
- usesec := sec - onsec;
- if usesec < 0 then begin
- usesec := usesec + 60;
- usemin := -1;
- end;
- usemin := min - onmin + usemin;
- if usemin < 0 then begin
- usemin := usemin + 60;
- usehour := -1;
- end;
- usehour := hour - onhour + usehour;
- if usehour < 0 then usehour := usehour + 24;
- end;
-
- procedure connecttime;
-
- var
- message: name;
-
- begin
- if clockin then begin
- calcconnect(usehour, usemin, usesec);
- message := copy(time(1, 1, usehour, usemin, usesec), 1, 8);
- lineout('Connect time: ' + message);
- end;
- end;
-
- procedure searchlib(infile: name; var result, libsects: integer);
-
- {Library-file support adapted from DELIB.PAS
- by Bela Lubkin of Borland International.}
-
- var
- temp: name;
- dirlength, offset, firstsec, loop, chrpos: integer;
-
- begin
- firstsec := 0; libsects := 0;
- blockread(libfile, libbuff, 1);
- if libbuff[0] <> 0 then result := 1;
- loop := 1;
- while (result = 0) and (loop <= 11) do begin
- if libbuff[loop] <> 32 then result := 1;
- loop := loop + 1;
- end;
- result := result + libbuff[12] + libbuff[13];
- if result = 0 then begin
- dirlength := libbuff[14] + 256*libbuff[15];
- if dirlength = 0 then result := 1;
- end;
- if result = 0 then begin
- loop := 0;
- while (loop < 4*dirlength-1) and (result = 0) and (firstsec = 0) do begin
- loop := loop + 1;
- offset := 32*(loop mod 4);
- if offset = 0 then blockread(libfile, libbuff, 1);
- if libbuff[offset] <> 0 then result := 1
- else begin
- temp := '';
- for chrpos := 1 to 8 do
- if libbuff[offset + chrpos] <> 32 then
- temp := temp + chr(libbuff[offset + chrpos]);
- if libbuff[offset + 9] <> 32 then begin
- temp := temp + '.';
- for chrpos := 9 to 11 do
- if libbuff[offset + chrpos] <> 32 then
- temp := temp + chr(libbuff[offset + chrpos]);
- end;
- if cts and (infile = 'DIR') then lineout(temp);
- if infile = temp then begin
- firstsec := libbuff[offset+12] + 256*libbuff[offset+13];
- libsects := libbuff[offset+14] + 256*libbuff[offset+15];
- seek(libfile, firstsec);
- end;
- end;
- end;
- if infile = 'DIR' then result := 0;
- end;
- end;
-
- procedure libassign(filename: longname; var result: integer);
-
- var
- infile: name;
- slash: integer;
- library: boolean;
-
- begin
- result := 0;
- slash := pos('/', filename);
- library := (slash > 0);
- if library then begin
- infile := copy(filename, slash + 1, length(filename) - slash);
- filename := copy(filename, 1, slash - 1);
- if pos('.', filename) = 0 then filename := filename + '.LBR';
- end;
- assign(libfile, filename);
- {$I-} reset(libfile) {$I+};
- result := IOresult;
- if result = 0 then
- if library then searchlib(infile, result, libsects)
- else libsects := filesize(libfile);
- libeof := (libsects = 0);
- end;
-
- procedure libblockread(var fileblock: filbuffer);
-
- begin
- if libsects > 0 then blockread(libfile, fileblock, 1);
- libsects := libsects - 1;
- if libsects = 0 then libeof := true;
- end;
-
- procedure typefile(fname: longname; nowrap: boolean);
-
- {Inline unsqueezer adapted from USQ.PAS V1.3, which
- was written by Scott Loftesness, adapted for Turbo
- Pascal by Steve Freeman and made compatible with
- Non-Turbo Pascal squeezers by myself.- BM}
-
- const
- recognize = $FF76;
- numvals = 257; { max tree size + 1 }
- speof = 256; { special end of file marker }
- dle: char = #$90;
-
- type
- tree = array [0..255,0..1] of integer;
-
- var
- in_ptr, result: integer;
- in_buff: filbuffer;
- dnode: tree;
- inchar, curin, filecksum, bpos, i, repct, numnodes: integer;
- c, lastchar: char;
- origfile: name;
- squeezed, eofin: boolean;
-
- function getc: integer;
-
- begin
- in_ptr := in_ptr + 1;
- if in_ptr > 127 then begin
- if libeof then eofin := true
- else begin
- libblockread(in_buff);
- in_ptr := 0;
- end;
- end;
- if eofin then getc := 26 else getc := in_buff[in_ptr];
- end;
-
- function getw: integer;
-
- var in1,in2: integer;
-
- begin
- in1 := getc; in2 := getc;
- getw := in1 + in2 shl 8;
- end;
-
- procedure initialize;
-
- var str: string[14];
-
- begin
- in_ptr := 127; squeezed := true;
- repct:=0; bpos:=99; origfile:=''; eofin:=false;
- i := getw;
- if (recognize <> i) then begin
- squeezed := false;
- in_ptr := -1;
- end
- else begin
- filecksum := getw; { get checksum from chars 2 - 3 of file }
- repeat { build original file name }
- inchar:=getc;
- if inchar <> 0
- then origfile := origfile + chr(inchar);
- until inchar = 0;
- lineout('Original file: ' + origfile);
- numnodes:=ord(getw); { get the number of nodes in this files tree }
- if (numnodes<0) or (numnodes>=numvals) then begin
- squeezed := false;
- in_ptr := -1;
- end;
- end;
- if squeezed then begin
- dnode[0,0]:= -(speof+1);
- dnode[0,1]:= -(speof+1);
- numnodes:=numnodes-1;
- for i:=0 to numnodes do begin
- dnode[i,0]:=getw;
- dnode[i,1]:=getw;
- end;
- end;
- end;
-
- function getuhuff: char;
-
- var i: integer;
-
- begin
- i:=0;
- repeat
- bpos:=bpos+1;
- if bpos>7 then begin
- curin := getc;
- bpos:=0;
- end
- else curin := curin shr 1;
- i := ord(dnode[i,ord(curin and $0001)]);
- until (i<0);
- i := -(i+1);
- if i=speof then begin
- eofin:=true;
- getuhuff:=chr(26);
- end
- else getuhuff:=chr(i);
- end;
-
- function getcr: char;
-
- var c: char;
-
- begin
- if squeezed then begin
- if (repct>0) then begin
- repct:=repct-1;
- getcr:=lastchar;
- end
- else begin
- c:=getuhuff;
- if c<>dle then begin
- getcr:=c;
- lastchar:=c;
- end
- else begin
- repct:=ord(getuhuff);
- if repct=0 then getcr:=dle
- else begin
- repct:=repct-2;
- getcr:=lastchar;
- end;
- end;
- end;
- end
- else getcr := chr(getc);
- end; {getcr}
-
- begin
- libassign(fname, result);
- if result <> 0 then lineout('Can''t find ' + fname + '!')
- else begin
- initialize;
- while cts and not(cancelled or eofin) do begin
- c:=getcr;
- if c = #26 then eofin := true else begin
- if nowrap then begin
- if c <> #$8D then begin { <-- Allows no-wrap using WordStar files}
- c := chr(ord(c) and 127);
- if (c <> lnfd) then charout(c);
- if c = cr then charout(lf);
- end;
- end else sendout(c);
- end;
- end;
- close(libfile);
- end;
- unload;
- end;
-
- procedure outfile(fname: longname);
-
- begin
- typefile(fname, true);
- end;
-
- function findid(caller: person): integer;
-
- var
- usernum: integer;
- index: integer;
-
- begin
- usernum := 0;
- index := 0;
- lineout('Searching userlist...');
- {$I-} reset(idfile) {$I+};
- if IOresult <> 0 then rewrite(idfile);
- while (usernum = 0) and not eof(idfile) do begin
- index := index + 1;
- read(idfile, idrec);
- if idrec.user = caller then usernum := index;
- end;
- findid := usernum;
- end;
-
- procedure getcomments(maxline: integer);
-
- var
- comfile: file of line;
- linenum: integer;
- head, temp: line;
-
- begin
- str(maxline:1, temp);
- lineout('Enter comment: up to ' + temp + ' lines, enter empty line to quit.');
- lineout(space);
- linenum := 0;
- assign(comfile, 'COMMENTS.BBS');
- {$I-} reset(comfile) {$I+};
- if IOresult <> 0 then rewrite(comfile);
- seek(comfile, filesize(comfile));
- head := caller;
- if clockin then head := head + ' ' + timeon;
- repeat
- linenum := linenum + 1;
- str(linenum:2, temp);
- stringout(temp + ': ');
- temp := inputstring(echo);
- if temp <> '' then begin
- if linenum = 1 then write(comfile, head);
- write(comfile, temp);
- end;
- until (temp = '') or (linenum = maxline) or not cts;
- close(comfile);
- end;
-
- function nextuser: integer;
-
- var temp: integer;
-
- begin
- stringout('Finding space for new user: ');
- temp := findid('***');
- if temp = 0 then nextuser := 1 + filesize(idfile) else nextuser := temp;
- end;
-
- procedure savedefaults;
-
- begin
- if usernum = 0 then usernum := nextuser;
- with idrec do begin
- user := caller;
- if expert then exfl := 0 else exfl := 255;
- if clockin then lsto := timeon;
- lstm := nextmess-1;
- pass := password;
- clr := cs;
- acc := access;
- bsp := bs;
- lnf := lf;
- upc := caps;
- wid := width;
- end;
- seek(idfile, usernum - 1);
- write(idfile, idrec);
- end;
-
- procedure disconnect;
-
- var
- ch: char;
-
- begin
- clearsc;
- if not expert then lineout('Answering question with other than "Y" or "N" returns to BBS:');
- ch := getcap('Do you want to leave comments to the Sysop (Y/N)? ');
- if ch = 'Y' then getcomments(15);
- if (ch = 'N') or (ch = 'Y') or not cts then begin
- connecttime;
- lineout('Thanks for calling, ' + caller);
- savedefaults;
- hangup;
- end;
- end;